package db

import (
	mydb "filestore-rebuild/db/mysql"
	"github.com/go-sql-driver/mysql"
	"log"
)

func UploadFile(fileHash string, fileName string, fileSize int64, fileAddr string) bool {
	sqlStr := `insert into tbl_file (file_sha1, file_name, file_size, file_addr, status) values(?,?,?,?,?) `
	stmt, err := mydb.DBConn().Prepare(sqlStr)
	if err != nil {
		log.Printf("prepare statement failed, err: %s\n", err.Error())
		return false
	}
	defer stmt.Close()
	ret, err := stmt.Exec(fileHash, fileName, fileSize, fileAddr, 1)
	if err != nil {
		if errMysql, ok := err.(*mysql.MySQLError); ok {
			switch errMysql.Number {
			case 1062:
				log.Printf("File has exists.")
				return true
			default:
				log.Printf("failed to exec sql, err: %s", err.Error())
				return false
			}
		}
	}

	if affect, err := ret.RowsAffected(); err == nil && affect > 0 {
		return true
	}
	return false
}

func InsertUserFile(username, fileHash string, fileSize int64, fileName string) bool {
	sqlStr := `insert into tbl_user_file (user_name, file_sha1, file_size, file_name, status) values (?,?,?,?,?)`
	stmt, err := mydb.DBConn().Prepare(sqlStr)
	if err != nil {
		log.Printf("prepare statement failed, err: %s\n", err.Error())
		return false
	}
	defer stmt.Close()
	ret, err := stmt.Exec(username, fileHash, fileSize, fileName, 1)
	if err != nil {
		log.Printf("failed to exec sql, err: %s", err.Error())
		return false
	}

	if affect, err := ret.RowsAffected(); err == nil && affect > 0 {
		return true
	}
	return false
}

type TblFile struct {
	FileSha1   string
	FileSize   int64
	FileName   string
	UploadAt   string
	LastUpdate string
	Status     int
}

func GetUserFile(username string) []TblFile {
	sqlStr := `select file_sha1, file_size, file_name, upload_at, last_update, status from tbl_user_file where user_name = ?`
	var files []TblFile
	stmt, err := mydb.DBConn().Prepare(sqlStr)
	if err != nil {
		log.Printf("prepare statement failed, err: %s\n", err.Error())
		return nil
	}
	rows, err := stmt.Query(username)
	if err != nil {
		log.Printf("failed to queryl, err: %s", err.Error())
		return nil
	}
	for rows.Next() {
		var file TblFile
		rows.Scan(&file.FileSha1, &file.FileSize, &file.FileName, &file.UploadAt, &file.LastUpdate, &file.Status)
		files = append(files, file)
	}
	return files
}

func DeleteUserFile(username, filename, fileHash string) bool {
	// TODO 删除三个条件，用户名 文件名 哈希值
	sqlStr := `delete from tbl_user_file where user_name = ? and file_name = ? and file_sha1 = ?`
	stmt, err := mydb.DBConn().Prepare(sqlStr)
	if err != nil {
		log.Printf("Prepare statement error: %s\n", err.Error())
		return false
	}
	defer stmt.Close()
	ret, err := stmt.Exec(username, filename, fileHash)
	if err != nil {
		log.Printf("Delete error: %s\n", err.Error())
		return false
	}
	if affected, err := ret.RowsAffected(); err == nil && affected > 0 {
		return true
	}
	return false
}

func UpdateUserFileName(username, filehash, filename, newname string) bool {
	sqlStr := `update tbl_user_file set file_name = ? where user_name = ? and file_name = ? and file_sha1 = ?`
	stmt, err := mydb.DBConn().Prepare(sqlStr)
	if err != nil {
		log.Printf("prepare statement erro: %s\n", err.Error())
		return false
	}
	defer stmt.Close()
	ret, err := stmt.Exec(newname, username, filename, filehash)
	if err != nil {
		log.Printf("exec sql error: %s\n", err.Error())
		return false
	}
	if affected, err := ret.RowsAffected(); nil == err && affected > 0 {
		return true
	}
	return false
}

func CheckFileExists(filehash string, filesize int64) bool {
	sqlStr := `select * from tbl_file where file_sha1=? and file_size=? limit 1`
	stmt, err := mydb.DBConn().Prepare(sqlStr)
	if err != nil {
		log.Printf("Prepare statement error: %s\n", err.Error())
		return false
	}
	defer stmt.Close()
	rows, err := stmt.Query(filehash, filesize)
	if err != nil {
		log.Printf("Query error: %s\n", err.Error())
		return false
	} else if rows == nil {
		log.Printf("File '%s' not found", filehash)
		return false
	}
	pRows := mydb.ParseRows(rows)
	return len(pRows) > 0

}
